package br.com.empresa.biblioteca.model.infra;

import java.util.List;

import javax.persistence.EntityManager;
import javax.persistence.EntityManagerFactory;
import javax.persistence.EntityTransaction;
import javax.persistence.Persistence;
import javax.persistence.Query;

import br.com.empresa.biblioteca.model.entidade.Entidade;

public class DAO {

	protected final static EntityManagerFactory fabrica;
	private Class<? extends Entidade> classe;

	static {
		fabrica = Persistence.createEntityManagerFactory("biblioteca");
	}

	public DAO(Class<? extends Entidade> classe) {
		this.classe = classe;
	}

	public void incluir(Entidade entidade) {
		EntityManager gerente = fabrica.createEntityManager();
		try {
			EntityTransaction transacao = gerente.getTransaction();
			transacao.begin();
			gerente.persist(entidade);
			transacao.commit();
		} finally {
			if (gerente != null && gerente.isOpen()) {
				gerente.close();
			}
		}
	}

	public void alterar(Entidade entidade) {
		EntityManager gerente = fabrica.createEntityManager();
		try {
			EntityTransaction transacao = gerente.getTransaction();
			transacao.begin();
			gerente.merge(entidade);
			transacao.commit();
		} finally {
			if (gerente != null && gerente.isOpen()) {
				gerente.close();
			}
		}
	}

	public void excluir(Entidade entidade) {
		EntityManager gerente = fabrica.createEntityManager();
		try {
			EntityTransaction transacao = gerente.getTransaction();
			transacao.begin();
			gerente.remove(gerente.merge(entidade));
			transacao.commit();
		} finally {
			if (gerente != null && gerente.isOpen()) {
				gerente.close();
			}
		}
	}

	@SuppressWarnings("rawtypes")
	public List obterTodos() {
		EntityManager gerente = fabrica.createEntityManager();
		try {
			String jpql = "select x from " + classe.getSimpleName() + " x";
			Query consulta = gerente.createQuery(jpql);
			return consulta.getResultList();
		} finally {
			if (gerente != null && gerente.isOpen()) {
				gerente.close();
			}
		}
	}
}
